home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000 #2
/
Ham Radio 2000 - Volume 2.iso
/
HAMV2
/
TCP_IP
/
TNOS230S
/
PBBSCMD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-06
|
64KB
|
2,641 lines
/* NOTE: because of size, the previous 'mailbox.c' has been
* split in 3 parts:
* pbbscmd.c, containing the 'pbbs' subcommands,
* mailbox.c, containing some user mailbox commands, and
* mailbox2.c, containing the remaining user commands.
* 921125 - WG7J
*/
/* There are only two functions in this mailbox code that depend on the
* underlying protocol, namely mbx_getname() and dochat(). All the other
* functions can hopefully be used without modification on other stream
* oriented protocols than AX.25 or NET/ROM.
*
* SM0RGV 890506, most work done previously by W9NK
*
*** Changed 900114 by KA9Q to use newline mapping features in stream socket
* interface code; everything here uses C eol convention (\n)
*
* Numerous new commands and other changes by SM0RGV, 900120
*
* Gateway function now support outgoing connects with the user's call
* with inverted ssid. Users can connect to system alias as well...
* See also several mods in socket.c,ax25.c and others
* 11/15/91, WG7J/PA3DIS
*
* Userlogging, RM,VM and KM commands, and R:-line interpretation
* added 920307 and later, Johan. K. Reinalda, WG7J/PA3DIS
*
* Inactivity timeout-disconnect added 920325 and later - WG7J
*
*/
#include "global.h"
#include "ctype.h"
#include "commands.h"
#ifndef MSDOS
#include <time.h>
#endif
#ifdef UNIX
#include <sys/stat.h>
#endif
#include "timer.h"
#include "proc.h"
#include "socket.h"
#include "usock.h"
#include "session.h"
#include "smtp.h"
#include "ftpserv.h"
#include "bm.h"
#include "pool.h"
#include "assoc.h"
#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: pbbscmd.c,v 1.28 1997/09/07 00:31:16 root Exp root $";
#endif
#ifdef MAILBOX
#ifdef MSDOS
extern void mbmemory (void);
#endif
#ifdef EXPIRY
extern void Expiretick (void *);
#endif
extern char *mblookname (struct mbx * m, char *str);
extern int dombmovemail (int argc, char *argv[], void *p);
extern char *host_or_wpage_exp (char *to, int hier, int exphome, int *dns);
extern char *wpage_exp (char *to, int hier, int exphome);
extern char *permtest (char *path, long privs, const char *name, int mode, char *root, int thedir);
extern int dombkickone (int argc, char *argv[], void *p);
extern char Myalias[];
extern char MyBBS[AXALEN];
#ifdef EXPIRY
extern int ExpireActive;
extern char *ExpireArea;
extern time_t ExpireLast;
#endif
#ifdef MBFWD
extern char *mbxRCall;
#endif
extern char *Mbhaddress;
extern int BbsUsers;
extern int Totallogins, Tutorlogins[], BBSlogins;
#ifdef CONVERS
extern int Conflogins;
#endif
char *Mbprompt;
char *MMotd;
char *MExit;
char *Mtmsg;
char *MAttendedAt;
int MOTDalways = 0;
int MAttended = 0;
int MBnoSubjBell = 0;
int MBnoReturnReceipt = 0;
int enforceBhosts = 0;
int MBackfilter = 0;
int LoginTimer = 180;
#ifdef EXPIRY
#define HALFYEAR 182 /* used for expiring personal areas */
int PruneAge = HALFYEAR;
#endif
char Mbpasswd[MAXPWDLEN + 1] = "";
struct no_js *Exclude = (struct no_js *) NULL;
#ifdef ASKHOME
static char *Mbhome = NULLCHAR;
#endif
AarrayPtr Mbcustom = NULLASSOC;
#ifdef MBFWD
extern int MbForwarded;
int Mbfullsvc = 1;
#endif
#ifdef DELEGATE
int Mbdelegate = 1;
#endif
#ifdef AX25
int Mbaxpasswd = 0;
#endif
extern int MbSent;
extern int MbRead;
extern int MbRecvd;
const char *continents[] =
{
"euro", "medr", "indi", "mdle", "seas", "asia", "noam",
"ceam", "carb", "soam", "aunz", "epac", "npac", "spac",
"wpac", "nafr", "cafr", "safr", "antr"
};
#define numcontinents 19
#ifdef AX25
static char Uplink[] = "Uplink (%s)";
static char Downlink[] = "Downlink (%s)";
#endif
#ifdef NETROM
static char incircuit[] = "Circuit (%s @ %s%s%s)";
static char outcircuit[] = "Circuit (%s%s%s)";
#endif
static char Telnet[] = "Telnet (%s @ %s)";
static char Telnetdown[] = "Telnet (%s)";
static char Local[] = "Local (%s @ %s)";
const char *displayMBstatus (int state, int issysop);
int isaPBBShost (char *str);
#ifdef USERLOG
void updatedefaults (struct mbx * m, int homeonly);
void askrealname (struct mbx * m, int initial);
int dorealname (int argc, char *argv[], void *p);
#endif
char *findhome (char *name);
void askhome (struct mbx * m, int initial);
int dobbshome (int argc, char *argv[], void *p);
char *cmd_line (int argc, char *argv[], char stype);
int dostr (int argc, char *argv[], const char *cmdstr, const char *label, char **str);
static int dobbsdumperr (int argc, char *argv[], void *p);
static int dombnewscan (int argc, char *argv[], void *p);
static int dombarea (int argc, char *argv[], void *p);
static int dombmore (int argc, char *argv[], void *p);
static int dombnorreceipt (int argc, char *argv[], void *p);
#ifdef MAILCMDS
static int dombscan (int argc, char *argv[], void *p);
static int dombholdsumm (int argc, char *argv[], void *p);
static int dopbbsreview (int argc, char *argv[], void *p);
static int dombmport (int argc, char *argv[], void *p);
static int dombbonly (int argc, char *argv[], void *p);
static int dombsendquery (int argc, char *argv[], void *p);
static int dombholdall (int argc, char *argv[], void *p);
static int dombhold (int argc, char *argv[], void *p);
static int dombnobid (int argc, char *argv[], void *p);
#endif
static int dombalias (int argc, char *argv[], void *p);
static int donewmotdfile (int argc, char *argv[], void *p);
static int doattend (int argc, char *argv[], void *p);
static int dombnewuser (int argc, char *argv[], void *p);
static int dombmotd (int argc, char *argv[], void *p);
static int dombmotdalways (int argc, char *argv[], void *p);
static int domexit (int argc, char *argv[], void *p);
int dombusers (int argc, char *argv[], void *p);
int dombpast (int argc, char *argv[], void *p);
static int dojumpstart (int argc, char *argv[], void *p);
static int dombnrid (int argc, char *argv[], void *p);
static int dombsetpasswd (int argc, char *argv[], void *p);
static int dombenforce (int argc, char *argv[], void *p);
static int dombnoax25 (int argc, char *argv[], void *p);
static int dombuonly (int argc, char *argv[], void *p);
static int dombsonly (int argc, char *argv[], void *p);
static int dombmaint (int argc, char *argv[], void *p);
static int dombmaintstr (int argc, char *argv[], void *p);
static int dombmaintmode (int argc, char *argv[], void *p);
static int dombmaintclear (int argc, char *argv[], void *p);
extern int dombmailfor (int argc, char *argv[], void *p);
extern int dombstatus (int argc, char *argv[], void *p);
int dombmailstats (int argc, char *argv[], void *p);
static int dombtmsg (int argc, char *argv[], void *p);
#ifdef EXPIRY
static int dombprune (int argc, char *argv[], void *p);
static int dombpruneage (int argc, char *argv[], void *p);
static void mbpruning (int a, void *v1, void *v2);
extern void expire (char *, int);
#endif
static int dombackfilter (int argc, char *argv[], void *p);
static int domaildomain (int argc, char *argv[], void *p);
static int dombremote (int argc, char *argv[], void *p);
static int dombbump (int argc, char *argv[], void *p);
static int dombzap (int argc, char *argv[], void *p);
static int dombhideport (int argc, char *argv[], void *p);
static int domblogging (int argc, char *argv[], void *p);
static int dombmaxtimer (int argc, char *argv[], void *p);
static int dombmaxusers (int argc, char *argv[], void *p);
static int dombprompt (int argc, char *argv[], void *p);
static int dombcmd (int argc, char *argv[], void *p);
static int dombnosubjbell (int argc, char *argv[], void *p);
static int doaxpasswd (int argc, char *argv[], void *p);
static int domblogintimer (int argc, char *argv[], void *p);
#ifdef STRICT_CALL
static int dombstrict (int argc, char *argv[], void *p);
#endif
#ifdef DELEGATE
static int dombdelegate (int argc, char *argv[], void *p);
#endif
extern void updateFwd (char *who, char *area, long bid, long size);
extern void bbsbump (char *user, int zap);
#ifdef MBXTDISC
static int dombtdisc (int argc, char *argv[], void *p);
static int dombtdiscsysop (int argc, char *argv[], void *p);
#endif
#ifdef ASKHOME
static int dombhome (int argc, char *argv[], void *p);
#endif
#ifdef MBFWD
static int dombfullsvc (int argc, char *argv[], void *p);
#endif
#ifdef CONVERS
static int dombconvlink (int argc, char *argv[], void *p);
#endif
#if defined(TIPMAIL) && defined(ALLSERV)
static int dotimeout (int argc, char *argv[], void *p);
#endif
#ifdef REJECT
static int dombreject (int argc, char *argv[], void *p);
#endif
#ifdef CATALOG
#include "catalog.h"
#define CAT pbbscmd_catalog
#define bumpusage __STR(0)
#define zapusage __STR(1)
#define logging_str __STR(2)
#define holdall_str __STR(3)
#define maint_str __STR(4)
#define maintmode_str __STR(5)
#define maintclear_str __STR(6)
#define invalidcall __STR(7)
#define jumpstart_str __STR(8)
#define nrid_str __STR(9)
#define mbarea_str __STR(10)
#define scan_str __STR(11)
#define hold_str __STR(12)
#define fullsvc_str __STR(13)
#define delegate_str __STR(14)
#define nobid_str __STR(15)
#define query_str __STR(16)
#define convers_str __STR(17)
#define dumperr_str __STR(18)
#define attend_str __STR(19)
#define tdisc_str __STR(20)
#define tdiscsysop_str __STR(21)
#define maxtimer_str __STR(22)
#define maxusers_str __STR(23)
#define passwdusage __STR(24)
#define strusage __STR(25)
#define motdalways_str __STR(26)
#define allview_str __STR(27)
#define homeusage __STR(28)
#define promptusage __STR(29)
#define changehome_str __STR(30)
#define homeset_str __STR(31)
#define homesyntax __STR(32)
#define realname_as __STR(33)
#define realname_str __STR(34)
#define realname_change __STR(35)
#define realname_set __STR(36)
#define realname_syntax __STR(37)
#define past_header __STR(38)
#define queued_str __STR(39)
#define ms_logins __STR(40)
#define users_count __STR(41)
#define info_on __STR(42)
#define ipaddress_str __STR(43)
#define nolocal_str __STR(44)
#define message_oor __STR(45)
#define mr_syntax __STR(46)
#define fwd_daemon __STR(47)
#define tiptimeout_str __STR(48)
#ifdef CALLBOOK
#define callusage __STR(49)
#endif
#define usernoton __STR(50)
#define sysopchat __STR(51)
#define nosubj_str __STR(52)
#define enforce_str __STR(53)
#define maildomain_str __STR(54)
#define norreceipt_str __STR(55)
#define mbmore_str __STR(56)
#define ackfilter_str __STR(57)
#ifdef EXPIRY
#define pruneage_str __STR(58)
#endif
#define axpasswd_str __STR(59)
#define mbtimer_str __STR(60)
#else /* CATALOG */
static const char bumpusage[] = "Syntax: pbbs bump username\n";
static const char zapusage[] = "Syntax: pbbs zap username\n";
static const char logging_str[] = "Keep log of each PBBS login";
static const char holdall_str[] = "Hold all local messages for SYSOP review";
static const char maint_str[] = "BBS Maintenance";
static const char maintmode_str[] = "Use BBS Maintenance mode";
static const char maintclear_str[] = "Clear BBS (bump users) for BBS Maintenance mode";
static const char invalidcall[] = "Invalid call: %s\n";
static const char jumpstart_str[] = "Jump start on connect";
static const char nrid_str[] = "Netrom id prompt";
static const char mbarea_str[] = "New users get area indication in prompt";
static const char scan_str[] = "New users get 'new mail scan' permission";
static const char hold_str[] = "New users have mail entered held for review";
static const char fullsvc_str[] = "Full Service BBS";
static const char delegate_str[] = "Allow user delegation forwarding";
static const char nobid_str[] = "Accept Buls without BID";
static const char query_str[] = "Query after send";
static const char convers_str[] = "PBBS convers";
static const char dumperr_str[] = "BBS - Dump on error";
static const char attend_str[] = "Mailbox Attended flag";
static const char tdisc_str[] = "PBBS redundancy timer (sec)";
static const char tdiscsysop_str[] = "PBBS redundancy timer used for Sysops";
static const char maxtimer_str[] = "PBBS Maximum session time allowed (sec)";
static const char maxusers_str[] = "Maximum PBBS incoming users (%d max)";
static const char passwdusage[] = "Usage: pbbs password \"<sysop password>\"\n";
static const char strusage[] = "Usage: %s %s \"<your message>\"\n";
static const char motdalways_str[] = "Always display MOTD file";
static const char allview_str[] = "All users will view the 'motd' file on their next login!\n";
static const char homeusage[] = "Usage: pbbs home <your prompt string>\n";
static const char promptusage[] = "Usage: pbbs prompt \"prompt string\"\n";
static const char changehome_str[] = "\nChanging HOME BBS from '%s'! Enter name of new HOME...\n";
static const char homeset_str[] = "\nHOME BBS set to '%s'\n";
static const char homesyntax[] = "Syntax: HOME user @bbs\n";
static const char realname_as[] = "\nThe on-line callbook shows your real name as '%s'\n";
static const char realname_str[] = "Your real name is used along with your callsign when sending a message\n"
"If you wish to %s this, use the NAME command\n";
static const char realname_change[] = "\nChanging REAL NAME from '%s'!\nEnter the name you wish to be known by...\n";
static const char realname_set[] = "\nREAL NAME set to '%s'\n";
static const char realname_syntax[] = "Syntax: NAME user \"realname\"\n";
static const char past_header[] = "Past users:\nUser Logins Time since last User Logins Time since last\n";
static const char queued_str[] = "SMTP queued messages: %d\n";
static const char ms_logins[] = "Total Logins: %d (BBS: %d";
static const char users_count[] = "Users: %d\nCount: %d\n";
static const char info_on[] = "Information on %s %s\n";
static const char ipaddress_str[] = "%s's TCP/IP ADDRESS: %s\n";
static const char nolocal_str[] = "No local data found for '%s'\n";
static const char message_oor[] = "Message number out of range\n";
static const char mr_syntax[] = "Syntax: MR type filename toname [fromname]\n";
static const char fwd_daemon[] = "Forwarding Daemon: %s";
static const char tiptimeout_str[] = "Tip connection timeout";
#ifdef CALLBOOK
static const char callusage[] = "Usage: callserver <host> <port>\n";
#endif
static const char usernoton[] = "User '%s' not on BBS!\n";
static const char sysopchat[] = "\nSYSOP requests a chat.....\n\n";
static const char nosubj_str[] = "Strip bell characters from subject lines";
static const char enforce_str[] = "Enforce that all bulletins are sent with a '@host'";
static const char maildomain_str[] = "Force user@host to use DNS hostname rather than WPages";
static const char norreceipt_str[] = "Disable responses to Return Receipt requests";
static const char mbmore_str[] = "New users get this value for 'more after' lines";
static const char ackfilter_str[] = "Filter out all '/ack' lines in email messages";
static const char pruneage_str[] = "Number of days to save messages when pruning";
static const char axpasswd_str[] = "Require all non-anonyous, non-PBBS AX.25 users to provide password";
static const char mbtimer_str[] = "Login timeout delay (in seconds)";
#endif /* CATALOG */
static void smtpqueuecheck (void);
int Mbjumpstart = 1;
int Usenrid = 0;
int Usescan = 0;
int Usearea = 1;
int Usemore = 0;
int Usehold = 0;
int NoBid;
int MbLogging = 0;
static int PBBSmaildomain = 0;
#ifdef STRICT_CALL
int PBBSstrict = 0;
#endif
int MBXMaint = 0;
int MBXMaintMode = 1;
static int MBXMaintClear = 0;
char *MBXMaintStr;
int Mbsendquery = 1;
char Mbnrid[20];
#ifdef MBXTDISC
int32 Mbtdiscinit = 0;
int MbtdiscSysop = 1;
#endif
int32 mbxMaxTimer = 0;
int mbxMaxUsers;
extern int MbHoldall;
#ifdef REJECT
int MbReject = 0;
#endif
/* pbbs subcommand table */
static struct cmds Mbtab[] =
{
{ "ackfilter", dombackfilter, 0, 0, NULLCHAR },
{ "alias", dombalias, 0, 0, NULLCHAR },
{ "attend", doattend, 0, 0, NULLCHAR },
{ "ax25passwd", doaxpasswd, 0, 0, NULLCHAR },
{ "bbsdumperr", dobbsdumperr, 0, 0, NULLCHAR },
#if defined(MAILCMDS) && defined(AX25)
{ "bbsonly", dombbonly, 0, 0, NULLCHAR },
#endif
{ "bump", dombbump, 0, 2, "pbbs bump <bbsuser>" },
#if defined(FOQ_CMDS) && defined(ALLSERV)
{ "chat", dombchat, 0, 2, "pbbs chat <bbsuser>" },
#endif
{ "cmd", dombcmd, 0, 0, NULLCHAR },
#ifdef CONVERS
{ "convers", dombconvlink, 0, 0, NULLCHAR },
#endif
#ifdef MAILCMDS
#ifdef DELEGATE
{ "delegate", dombdelegate, 0, 0, NULLCHAR },
#endif
{ "enforce", dombenforce, 0, 0, NULLCHAR },
#ifdef MBFWD
{ "fullservice",dombfullsvc, 0, 0, NULLCHAR },
#endif
#endif
#ifdef MAILCMDS
{ "holdsummary",dombholdsumm, 0, 0, NULLCHAR },
#endif
{ "hideport", dombhideport, 0, 0, NULLCHAR },
#ifdef MAILCMDS
{ "holdall", dombholdall, 0, 0, NULLCHAR },
#endif
#ifdef ASKHOME
{ "home", dombhome, 0, 0, NULLCHAR },
#endif
#ifdef AX25
{ "jumpstart", dojumpstart, 0, 0, NULLCHAR },
#endif
{ "logging", domblogging, 0, 0, NULLCHAR },
{ "logintimer", domblogintimer, 0, 0, NULLCHAR },
{ "maildomain", domaildomain, 0, 0, NULLCHAR },
#if defined(MAILFOR) && defined(AX25) && defined(MAILCMDS)
{ "mailfor", dombmailfor, 0, 0, NULLCHAR },
#endif
{ "mailstats", dombmailstats, 0, 0, NULLCHAR },
{ "maintenance",dombmaint, 0, 0, NULLCHAR },
{ "maintclear", dombmaintclear, 0, 0, NULLCHAR },
{ "maintmode", dombmaintmode, 0, 0, NULLCHAR },
{ "maintstr", dombmaintstr, 0, 0, NULLCHAR },
{ "maxtimer", dombmaxtimer, 0, 0, NULLCHAR },
{ "maxusers", dombmaxusers, 0, 0, NULLCHAR },
{ "mexit", domexit, 0, 0, NULLCHAR },
{ "motd", dombmotd, 0, 0, NULLCHAR },
{ "motdalways", dombmotdalways, 0, 0, NULLCHAR },
#if defined(AX25) && defined(MAILCMDS)
{ "mport", dombmport, 0, 0, NULLCHAR },
#endif
{ "newuser", dombnewuser, 0, 0, NULLCHAR },
{ "newmotdfile",donewmotdfile, 0, 0, NULLCHAR },
#ifdef AX25
{ "noax25", dombnoax25, 0, 0, NULLCHAR },
#endif
#ifdef MAILCMDS
{ "nobid", dombnobid, 0, 0, NULLCHAR },
#endif
{ "norreceipt", dombnorreceipt, 0, 0, NULLCHAR },
{ "nosubjbell", dombnosubjbell, 0, 0, NULLCHAR },
{ "past", dombpast, 0, 0, NULLCHAR },
{ "password", dombsetpasswd, 0, 0, NULLCHAR },
{ "prompt", dombprompt, 0, 0, NULLCHAR },
#ifdef EXPIRY
{ "prune", dombprune, 0, 0, NULLCHAR },
{ "pruneage", dombpruneage, 0, 0, NULLCHAR },
#endif
#ifdef MAILCMDS
{ "review", dopbbsreview, 0, 0, NULLCHAR },
#endif
#ifdef REJECT
{ "reject", dombreject, 0, 0, NULLCHAR },
#endif
{ "remote", dombremote, 0, 0, NULLCHAR },
#ifdef MAILCMDS
{ "scan", dombscan, 0, 2, "pbbs scan <bbsuser>" },
{ "sendquery", dombsendquery, 0, 0, NULLCHAR },
#endif
{ "status", dombstatus, 0, 0, NULLCHAR },
#ifdef STRICT_CALL
{ "strictcall", dombstrict, 0, 0, NULLCHAR },
#endif
#ifdef AX25
{ "sysoponly", dombsonly, 0, 0, NULLCHAR },
#endif
#ifdef MBXTDISC
{ "tdisc", dombtdisc, 0, 0, NULLCHAR },
{ "tdiscsysop", dombtdiscsysop, 0, 0, NULLCHAR },
#endif
#if defined(TIPMAIL) && defined(ALLSERV)
{ "tiptimeout", dotimeout, 0, 0, NULLCHAR },
#endif
{ "tmsg", dombtmsg, 0, 0, NULLCHAR },
#ifdef AX25
{ "usersonly", dombuonly, 0, 0, NULLCHAR },
#endif
{ "zap", dombzap, 0, 0, NULLCHAR },
{ NULLCHAR, NULL, 0, 0, NULLCHAR }
};
/* pbbs newuser subcommand table */
static struct cmds Mbnewtab[] =
{
{ "area", dombarea, 0, 0, NULLCHAR },
#ifdef MAILCMDS
{ "hold", dombhold, 0, 0, NULLCHAR },
#endif
{ "more", dombmore, 0, 0, NULLCHAR },
#ifdef AX25
{ "nrid", dombnrid, 0, 0, NULLCHAR },
#endif
{ "scan", dombnewscan, 0, 0, NULLCHAR },
{ NULLCHAR, NULL, 0, 0, NULLCHAR }
};
/*set the mailbox netrom id*/
void
setmbnrid ()
{
char tmp[AXBUF];
#ifdef NETROM
char tmp2[AXBUF];
#endif
#ifndef AX25
char *cp;
#endif
#ifdef NETROM
if (Nr_iface != NULLIF) { /* Use netrom call, and alias (if exists) */
if (*Myalias != '\0')
sprintf (Mbnrid, "%s:%s ", pax25 (tmp, Myalias), pax25 (tmp2, Nr_iface->hwaddr));
else
sprintf (Mbnrid, "%s ", pax25 (tmp, Nr_iface->hwaddr));
return;
}
/* Use Mycall, and alias (if exists) */
if (*Myalias != '\0')
sprintf (Mbnrid, "%s:%s ", pax25 (tmp, Myalias), pax25 (tmp2, Mycall));
else
#endif
#ifdef AX25
sprintf (Mbnrid, "%s ", pax25 (tmp, Mycall));
#else
strncpy (Mbnrid, Hostname, 19);
if ((cp = strchr (Mbnrid, '.')) != NULLCHAR)
*cp = '\0';
#endif
return;
}
/*This is a dummy called from the main command interpreter,
*setup a mbx structure so dombusers() works correct - WG7J
*/
int
dombstatus (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
{
struct mbx m;
m.privs = SYSOP_CMD;
m.stype = ' ';
return dombusers (0, NULL, &m);
}
static int
dombbump (int argc, char *argv[], void *p OPTIONAL)
{
if (argc == 1)
tputs (bumpusage);
else
bbsbump (argv[1], 0);
return 0;
}
static int
dombzap (int argc, char *argv[], void *p OPTIONAL)
{
if (argc == 1)
tputs (zapusage);
else
bbsbump (argv[1], 1);
return 0;
}
int
domaildomain (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&PBBSmaildomain, maildomain_str, argc, argv);
}
#ifdef STRICT_CALL
int
dombstrict (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&PBBSstrict, "Allow login from callsigns, only", argc, argv);
}
#endif
int
domblogging (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MbLogging, logging_str, argc, argv);
}
int
dombenforce (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&enforceBhosts, enforce_str, argc, argv);
}
int
dombackfilter (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MBackfilter, ackfilter_str, argc, argv);
}
#ifdef MAILCMDS
int
dombholdall (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MbHoldall, holdall_str, argc, argv);
}
static int
dombnobid (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&NoBid, nobid_str, argc, argv);
}
static int
dombsendquery (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&Mbsendquery, query_str, argc, argv);
}
static int
dombholdsumm (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
{
struct mbx m;
tputc ('\n');
m.privs = SYSOP_CMD;
m.stype = 'H';
return doarea (0, NULLCHARP, &m);
}
static int
dombscan (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
{
struct mbx m;
char *buf;
long perm;
tputc ('\n');
m.privs = 0;
m.stype = ' ';
strncpy (m.name, argv[1], 20);
(void) strupr (m.name);
if ((buf = userlookup (m.name, NULLCHARP, NULLCHARP, &perm, NULL)) != NULLCHAR) {
m.privs = perm;
free (buf);
}
quickscan (&m, 1, 1);
return 0;
}
static int
dopbbsreview (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
{
struct mbx m;
int oldflow = Command->flowmode;
tputc ('\n');
m.privs = SYSOP_CMD | FTP_WRITE;
m.stype = ' ';
m.morerows = 0;
m.quickfile = (FILE *) -1;
m.sid = 0;
m.user = Curproc->output;
m.mfile = NULLFILE;
m.area[0] = 0;
strcpy (m.name, "sysop");
if (Curproc->input == Command->input)
Command->flowmode = 1;
(void) dombreview (0, NULLCHARP, &m);
Command->flowmode = oldflow;
return 0;
}
#endif
#ifdef REJECT
int
dombreject (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MbReject, "Process 'reject.dat' file", argc, argv);
}
#endif
int
dombmaint (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MBXMaint, maint_str, argc, argv);
}
int
dombmaintmode (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MBXMaintMode, maintmode_str, argc, argv);
}
int
dombmaintclear (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MBXMaintClear, maintclear_str, argc, argv);
}
int
dopbbs (int argc, char *argv[], void *p)
{
if (argc == 1)
return dombstatus (0, NULL, NULL);
return subcmd (Mbtab, argc, argv, p);
}
int
dombnewuser (int argc, char *argv[], void *p)
{
return subcmd (Mbnewtab, argc, argv, p);
}
#ifdef AX25
static int
dombhideport (int argc, char *argv[], void *p)
{
return (dosetflag (argc, argv, p, HIDE_PORT, 1));
}
static int
dojumpstart (int argc, char *argv[], void *p OPTIONAL)
{
register int i;
char tmp[AXBUF];
struct no_js *ep;
if ((argc > 1) && (*argv[1] == 'e')) {
/*the exclude subcommand*/
if (argc == 2) { /* just list them */
for (ep = Exclude; ep != (struct no_js *) NULL; ep = ep->next)
tprintf ("%s ", pax25 (tmp, ep->call));
tputc ('\n');
} else { /* add some call(s) */
for (i = 0; i < argc - 2; i++) {
ep = callocw (1, sizeof (struct no_js));
if (setcall (ep->call, argv[i + 2]) == -1) {
tprintf (invalidcall, argv[i + 2]);
free (ep);
} else { /* add to list */
ep->next = Exclude;
Exclude = ep;
}
}
}
return 0;
}
return setbool (&Mbjumpstart, jumpstart_str, argc, argv);
}
static int
dombnrid (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&Usenrid, nrid_str, argc, argv);
}
#ifdef MAILCMDS
static int
dombmport (int argc, char *argv[], void *p)
{
return (dosetflag (argc, argv, p, MAIL_BEACON, 1));
}
static int
dombhold (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&Usehold, hold_str, argc, argv);
}
#endif
static int
dombnoax25 (int argc, char *argv[], void *p)
{
return (dosetflag (argc, argv, p, NO_AX25, 1));
}
#endif /* AX25 */
static int
dombarea (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&Usearea, mbarea_str, argc, argv);
}
static int
domblogintimer (int argc, char *argv[], void *p OPTIONAL)
{
return setint (&LoginTimer, mbtimer_str, argc, argv);
}
static int
dombmore (int argc, char *argv[], void *p OPTIONAL)
{
return setint (&Usemore, mbmore_str, argc, argv);
}
static int
dombnewscan (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&Usescan, scan_str, argc, argv);
}
static int
dombnosubjbell (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MBnoSubjBell, nosubj_str, argc, argv);
}
static int
dombnorreceipt (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MBnoReturnReceipt, norreceipt_str, argc, argv);
}
#ifdef MBFWD
static int
dombfullsvc (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&Mbfullsvc, fullsvc_str, argc, argv);
}
#endif
static int
doaxpasswd (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&Mbaxpasswd, axpasswd_str, argc, argv);
}
#ifdef DELEGATE
static int
dombdelegate (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&Mbdelegate, delegate_str, argc, argv);
}
#endif
#ifdef CONVERS
int Mbconverse = 1;
static int
dombconvlink (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&Mbconverse, convers_str, argc, argv);
}
#endif
int BBSdump = 1;
static int
dobbsdumperr (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&BBSdump, dumperr_str, argc, argv);
}
/* if unattended mode is set, ax25, telnet and maybe other sessions will
* be restricted.
*/
static int
doattend (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MAttended, attend_str, argc, argv);
}
#ifdef MBXTDISC
/* Set mailbox redundancy timer */
static int
dombtdisc (int argc, char *argv[], void *p OPTIONAL)
{
return setlong (&Mbtdiscinit, tdisc_str, argc, argv);
}
/* Set mailbox redundancy timer mode for sysops */
static int
dombtdiscsysop (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MbtdiscSysop, tdiscsysop_str, argc, argv);
}
#endif
/* Set mailbox maximum session timer */
static int
dombmaxtimer (int argc, char *argv[], void *p OPTIONAL)
{
return setlong (&mbxMaxTimer, maxtimer_str, argc, argv);
}
/* Set mailbox maximum user count */
static int
dombmaxusers (int argc, char *argv[], void *p OPTIONAL)
{
char buf[50];
sprintf (buf, maxusers_str, NUMMBX);
return setint (&mbxMaxUsers, buf, argc, argv);
}
static int
dombsetpasswd (int argc, char *argv[], void *p OPTIONAL)
{
int len;
/*Only allowed from keyboard*/
if (Curproc->input != Command->input) {
tputs (Noperm);
return 0;
}
if (argc != 2) {
tputs (passwdusage);
return 0;
}
if ((len = (int) strlen (argv[1])) == 0)
return 0; /* zero length, don't reset */
if (len > MAXPWDLEN) {
tputs ("Too long\n");
return 0;
}
strncpy (Mbpasswd, argv[1], MAXPWDLEN);
return 0;
}
/* define the BBS alias*/
static int
dombalias (int argc, char *argv[], void *p OPTIONAL)
{
char tmp[AXBUF];
if (argc < 2) {
tprintf ("%s\n", pax25 (tmp, MyBBS));
return 0;
}
if (setcall (MyBBS, argv[1]) == -1) {
tputs ("can't set BBS alias\n");
return 0;
}
return 0;
}
int
dostr (int argc, char *argv[], const char *cmdstr, const char *label, char **str)
{
if (argc > 2) {
tprintf (strusage, (cmdstr) ? cmdstr : "pbbs", label);
return 0;
}
if (argc < 2) {
if (*str != NULLCHAR) {
tputs (*str);
if (str[0][strlen (*str) - 1] != '\n')
tputs ("\n");
}
} else {
if (*str != NULLCHAR) {
free (*str);
*str = NULLCHAR; /* reset the pointer */
}
if (!strlen (argv[1]))
return 0; /* clearing the buffer */
*str = mallocw (strlen (argv[1]) + 5); /* allow for the EOL char */
strcpy (*str, argv[1]);
strcat (*str, "\n"); /* add the EOL char */
}
return 0;
}
static int
dombmaintstr (int argc, char *argv[], void *p OPTIONAL)
{
return dostr (argc, argv, NULLCHAR, "maintstr", &MBXMaintStr);
}
static int
dombmotd (int argc, char *argv[], void *p OPTIONAL)
{
return dostr (argc, argv, NULLCHAR, "motd", &MMotd);
}
static int
dombmotdalways (int argc, char *argv[], void *p OPTIONAL)
{
return setbool (&MOTDalways, motdalways_str, argc, argv);
}
static int
dombremote (int argc, char *argv[], void *p OPTIONAL)
{
return dostr (argc, argv, NULLCHAR, "remote", &MAttendedAt);
}
static int
donewmotdfile (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
{
#ifdef USERLOG
FILE *Ufile, *tfile;
char buf[256], *cp;
/* Save old defaults file to backup */
unlink (UDefbak);
if (rename (UDefaults, UDefbak))
return 0;
if ((tfile = fopen (UDefbak, "r")) != NULLFILE) {
if ((Ufile = fopen (UDefaults, "w")) == NULLFILE) {
(void) fclose (tfile);
return 0;
}
while (fgets (buf, sizeof (buf), tfile) != NULLCHAR) {
if ((cp = strchr (buf, ' ')) != NULLCHAR)
if ((cp = strchr (cp, ' ')) != NULLCHAR)
if ((cp = strchr (cp, ')')) != NULLCHAR)
if ((cp = strchr (cp, 'R')) != NULLCHAR)
*cp = ' ';
fputs (buf, Ufile);
}
(void) fclose (tfile);
(void) fclose (Ufile);
tputs (allview_str);
} else
(void) rename (UDefbak, UDefaults);
return 0;
#endif
}
static int
domexit (int argc, char *argv[], void *p OPTIONAL)
{
return dostr (argc, argv, NULLCHAR, "mexit", &MExit);
}
static int
dombtmsg (int argc, char *argv[], void *p OPTIONAL)
{
return dostr (argc, argv, NULLCHAR, "tmsgs", &Mtmsg);
}
#ifdef ASKHOME
/* Set the HOME BBS prompt string to be used */
static int
dombhome (int argc, char *argv[], void *p OPTIONAL)
{
if (argc > 2) {
tputs (homeusage);
return 0;
}
if (argc < 2) {
if (Mbhome != NULLCHAR)
tprintf ("%s\n", Mbhome);
} else {
if (Mbhome != NULLCHAR) {
free (Mbhome);
Mbhome = NULLCHAR; /* reset the pointer */
}
if (!strlen (argv[1]))
return 0; /* clearing the buffer */
Mbhome = strdup (argv[1]);
}
return 0;
}
#endif /* ASKHOME */
/* Set a custom BBS prompt string*/
static int
dombprompt (int argc, char *argv[], void *p OPTIONAL)
{
if (argc > 2)
tputs (promptusage);
else if (argc < 2) {
if (Mbprompt != NULLCHAR)
tprintf ("%s\n", Mbprompt);
} else {
if (Mbprompt != NULLCHAR) {
free (Mbprompt);
Mbprompt = NULLCHAR; /* reset the pointer */
}
if (!strlen (argv[1]))
return 0; /* clearing the buffer */
Mbprompt = strdup (argv[1]);
}
return 0;
}
/* Keep track of all past users */
struct pu {
struct pu *next; /* next one in list */
char name[20]; /* user name */
int32 time; /* When was the last login ? */
int number; /* Number of times logged in */
};
#define NULLPU (struct pu *)NULL
static struct pu *Pu = NULLPU;
static struct pu *pu_lookup (char *name);
#ifdef POOLED
static struct mempool Pu_pool = {NULLPOOLBLK, NULLPOOLBLK, 0, sizeof (struct pu), 50};
#endif
/* Look up an entry in the users-list*/
static struct pu *
pu_lookup (char *name)
{
register struct pu *ppu;
struct pu *pulast = NULLPU;
for (ppu = Pu; ppu != NULLPU; pulast = ppu, ppu = ppu->next) {
if (!strcmp (name, ppu->name)) { /* found it! */
if (pulast != NULLPU) {
/* Move entry to top of list */
pulast->next = ppu->next;
ppu->next = Pu;
Pu = ppu;
}
return ppu;
}
}
return NULLPU;
}
/*Log all users of the mailbox*/
/* This gets kept track of in the file name UDefaults */
/* format is
user @home (realname) datestamp options
where options are separated by spaces
M# - use more with # lines
A - use area indiation
X - use expert status
N - use netrom lookalike prompt
R - has the motd file been read?
S - give new message statistics on login
L - use LZW compressed streams
G - use ANSI color graphics
D - forwarding delegation enabled?
Cx - Connection type x (A=AX.25, N=NET/ROM, T=TELNET)
*/
#ifdef USERLOG
/* Write the new defaults - WG7J */
void
updatedefaults (struct mbx *m, int homeonly)
{
FILE *Ufile, *tfile;
char buf[256];
char *cp, *cp2;
time_t t;
/* Save old defaults file to backup */
unlink (UDefbak);
if (rename (UDefaults, UDefbak))
return;
/*Write all users back, but update this one!*/
if ((Ufile = fopen (UDefaults, "w")) == NULLFILE) {
/* Can't create defaults file ???*/
(void) rename (UDefbak, UDefaults);
return;
}
if ((tfile = fopen (UDefbak, "r")) == NULLFILE) {
/* What on earth happened ???? */
(void) fclose (Ufile);
(void) rename (UDefbak, UDefaults);
return;
}
while (fgets (buf, sizeof (buf), tfile) != NULLCHAR) {
if ((cp = strchr (buf, ' ')) == NULLCHAR)
continue;
*cp = '\0';
if (!stricmp (m->name, buf)) {
/*found this user*/
(void) time (&t);
if (homeonly == 1) {
if ((cp = strchr (++cp, ' ')) == NULLCHAR)
continue;
cp++;
if (*cp == '@') {
if ((cp = strchr (++cp, ' ')) == NULLCHAR)
continue;
cp++;
}
cp = strdup (cp);
sprintf (buf, "%s %s %s", m->name, m->home, cp);
free (cp);
} else if (homeonly == 2) {
*cp = ' ';
if ((cp = strchr (++cp, ' ')) == NULLCHAR)
continue;
*cp++ = 0;
if (*cp == '(') {
if ((cp = strchr (++cp, ')')) == NULLCHAR)
continue;
cp += 2;
}
cp = strdup (cp);
cp2 = strdup (buf);
sprintf (buf, "%s (%s) %s", cp2, m->realname, cp);
free (cp);
free (cp2);
} else {
char *tmpcp = 0, *tmpcp2, *tmpcp3 = 0;
if (m->home) {
tmpcp3 = tmpcp = strdup (m->home);
tmpcp2 = strchr (tmpcp, '@');
if (tmpcp2)
tmpcp3 = ++tmpcp2;
tmpcp2 = strchr (tmpcp3, '.');
if (tmpcp2)
*tmpcp2 = 0;
}
sprintf (buf, "%s @%s %s %lu M%d %s%s%s%s%s%s%s%s%s C%c\n",
m->name,
(m->home && Hostname && strnicmp (m->home, Hostname, strlen (m->home)))
? tmpcp3 : "",
(m->realname) ? m->realname : "()",
t, m->morerows,
(m->sid & MBX_AREA) ? "A" : "",
(m->sid & MBX_DELEGATE) ? "D" : "",
(m->sid & MBX_GFX) ? "G" : "",
(m->sid & MBX_HOLD) ? "H" : "",
(m->sid & MBX_TNOS) ? "L" : "",
(m->sid & MBX_NRID) ? "N" : "",
(m->sid & MBX_RDMOTD) ? "R" : "",
(m->sid & MBX_STATS) ? "S" : "",
(m->sid & MBX_EXPERT) ? "X" : "",
(m->family == AF_AX25) ? 'A' : \
((m->family == AF_NETROM) ? 'N' : 'T'));
if (m->home)
free (tmpcp);
}
} else
*cp = ' '; /* restore the space !*/
fputs (buf, Ufile);
}
(void) fclose (tfile);
(void) fclose (Ufile);
return;
}
#endif /* USERLOG */
#ifdef ASKHOME
char *
findhome (char *name)
{
char buf[256];
register char *cp, *cp2;
char *retval = (char *) 0;
register FILE *Ufile;
if ((Ufile = fopen (UDefaults, "r")) != NULLFILE) {
while (fgets (buf, sizeof (buf), Ufile) != NULLCHAR) {
if ((cp = strchr (buf, ' ')) == NULLCHAR)
continue;
*cp++ = '\0';
if (!stricmp (name, buf)) {
if ((cp2 = strchr (cp, ' ')) != NULLCHAR)
*cp2 = '\0';
if (*cp == '@') {
cp++;
if ((cp2 = strchr (cp, '.')) != NULLCHAR)
*cp2 = '\0';
if (!*cp)
retval = (char *) -1; /* -1 means home is here */
else if (*cp != '-')
retval = (char *) strdup (cp);
}
break;
}
}
(void) fclose (Ufile);
}
return (retval);
}
#endif /* ASKHOME */
void
askhome (struct mbx *m OPTIONAL, int initial OPTIONAL)
{
#ifdef ASKHOME
char *cp;
char name[80], here[AXBUF];
if (initial && m->privs & IS_BBS) {
m->home = strdup (m->name);
return;
}
#ifdef MBFWD
if (mbxRCall)
strncpy (here, mbxRCall, AXBUF);
else
#endif
(void) pax25 (here, Mycall);
if (initial) {
(void) DisplayFile (AskhomeFile, m->user);
if (Mbhome != NULLCHAR)
tputs (Mbhome);
strncpy (name, here, 80);
if ((cp = strchr (name, '.')) != NULLCHAR)
*cp = '\0';
m->home = strdup (name);
} else
tprintf (changehome_str, (m->home) ? m->home : here);
tputs ("\nHOME BBS>\n");
if (mbxrecvline (m) == -1)
return;
for (cp = m->line; isspace (*cp); ++cp)
;
if (*cp && *cp != '\n') {
free (m->home);
(void) strlwr (cp);
m->home = strdup (cp);
if ((cp = strchr (m->home, '.')) != NULLCHAR)
*cp = '\0';
m->change |= CHG_WP;
}
tprintf (homeset_str, (m->home) ? m->home : here);
updatedefaults (m, 0);
#endif
}
#if (defined(ASKHOME) || defined(WPAGES))
int
dobbshome (int argc, char *argv[], void *p)
{
struct mbx *m;
char *orgname, *orghome;
m = (struct mbx *) p;
if (argc > 1 && (m->privs & SYSOP_CMD)) {
if (argc == 2)
return (dombuserinfo (argc, argv, p));
if (argc > 3 || argv[2][0] != '@') {
tputs (homesyntax);
return (0);
}
orgname = strdup (m->name);
orghome = m->home;
strncpy (m->name, argv[1], 20);
m->home = argv[2];
updatedefaults (m, 1);
strncpy (m->name, orgname, 20);
m->home = orghome;
free (orgname);
} else
askhome (m, 0);
return 0;
}
#endif /* ASKHOME || WPAGES */
#ifdef USERLOG
void
askrealname (struct mbx *m, int initial)
{
char *cp;
char name[80];
char *callnm;
if (initial) {
callnm = mblookname (NULLMBX, m->name);
if (m->privs & IS_BBS) {
m->realname = strdup (m->name);
return;
}
if (callnm) {
m->realname = strdup (&callnm[1]);
free (callnm);
m->update = 1;
tprintf (realname_as, callnm);
} else
m->realname = strdup ("()");
tprintf (realname_str, (callnm) ? "change" : "set");
return;
}
tprintf (realname_change, (!m->realname || !strcmp (m->realname, "()")) ? "unknown" : m->realname);
tputs ("\nREAL NAME>\n");
if (mbxrecvline (m) == -1)
return;
cp = skipwhite (m->line);
if (*cp && *cp != '\n') {
free (m->realname);
sprintf (name, "(%s)", cp);
m->realname = strdup (name);
m->change |= CHG_WP;
}
tprintf (realname_set, (m->realname && strcmp (m->realname, "()")) ? m->realname : "unknown");
m->update = 1;
}
int
dorealname (int argc, char *argv[], void *p)
{
struct mbx *m;
char *orgname, *orgreal;
m = (struct mbx *) p;
if (argc > 1 && (m->privs & SYSOP_CMD)) {
if (argc == 2)
return (dombuserinfo (argc, argv, p));
if (argc > 3) {
tputs (realname_syntax);
return (0);
}
orgname = strdup (m->name);
orgreal = m->realname;
strncpy (m->name, argv[1], 20);
m->realname = argv[2];
updatedefaults (m, 2);
strncpy (m->name, orgname, 20);
m->realname = orgreal;
free (orgname);
} else
askrealname (m, 0);
return 0;
}
#endif
static int DiffUsers = 0;
time_t
loguser (struct mbx *m)
{
register struct pu *pu;
time_t t;
#ifdef USERLOG
FILE *Ufile = NULLFILE;
char buf[256];
char *cp;
int found = 0;
time_t laston = 0;
int xpert = 0;
#endif
(void) time (&t);
m->logontime = (long) t;
if ((pu = pu_lookup (m->name)) == NULLPU) { /* not 'known' user */
#ifdef POOLED
pu = (struct pu *) pool_alloc (&Pu_pool);
#else
pu = (struct pu *) callocw (1, sizeof (struct pu));
#endif
strncpy (pu->name, m->name, 20);
pu->next = Pu;
Pu = pu;
DiffUsers++; /* A new guy */
}
pu->time = secclock ();
pu->number++;
#ifdef USERLOG
/* Now get options from the userdefaults file, and add timestamp */
if (!(m->sid & MBX_SID)) { /* only if not a bbs */
sprintf (buf, "%s", UDefaults);
if ((Ufile = fopen (buf, "r+")) == NULLFILE) {
/* default file doesn't exist, create it */
if ((Ufile = fopen (buf, "w")) == NULLFILE)
return (time_t) - 1;
/* Add this user as first one,
* default uses Area indication
*/
m->home = strdup ("-");
(void) time (&t);
sprintf (buf, "%s @%s () %lu M%d %s%s%s%s%s C%c\n",
m->name,
(m->home && Hostname && strnicmp (m->home, Hostname, strlen (m->home)))
? m->home : "", t, m->morerows,
(m->privs & IS_BBS) ? "" : (Usearea) ? "A" : "",
(Usehold) ? "H" : "",
(Usenrid) ? "N" : "",
(Usescan) ? "S" : "",
(m->sid & MBX_EXPERT) ? "X" : "",
(m->family == AF_AX25) ? 'A' : \
((m->family == AF_NETROM) ? 'N' : 'T'));
fputs (buf, Ufile);
(void) fclose (Ufile);
m->realname = NULLCHAR;
if (!(m->privs & IS_BBS) && Usearea)
m->sid |= MBX_AREA;
if (Usenrid)
m->sid |= MBX_NRID;
if (Usescan)
m->sid |= MBX_STATS;
return laston;
}
/* Find user in the default file */
while (!found) {
if (fgets (buf, sizeof (buf), Ufile) == NULLCHAR)
break;
if ((cp = strchr (buf, ' ')) == NULLCHAR)
continue;
*cp++ = '\0';
if (!stricmp (m->name, buf)) {
/* found user, now scan the options used */
found = 1;
(void) fclose (Ufile);
if (*cp == '@') {
char *cp2;
if ((cp2 = strchr (cp++, ' ')) != NULLCHAR) {
*cp2++ = '\0';
if (*cp)
m->home = strdup (cp);
cp = cp2;
}
} else
m->home = strdup ("-");
cp = skipwhite (cp);
m->realname = NULLCHAR;
if (*cp == '(') {
char *cp2;
if ((cp2 = strchr (cp, ')')) != NULLCHAR) {
cp2++;
*cp2++ = '\0';
m->realname = strdup (cp);
cp = cp2;
}
}
cp = skipwhite (cp);
laston = atol (cp);
while (*cp != ' ') /* now skip the laston time */
cp++;
while (*cp != '\0') {
while (*cp == ' ') /*skip blanks*/
cp++;
switch (*cp) {
case 'C':
/* All options end BEFORE the CT/CN or CA */
*(cp + 1) = '\0';
break;
case 'H':
m->sid |= MBX_HOLD;
break;
case 'D':
m->sid |= MBX_DELEGATE;
break;
case 'M':
cp++;
m->morerows = atoi (cp);
break;
case 'A':
m->sid |= MBX_AREA;
break;
case 'G':
m->sid |= MBX_GFX;
m->usecolor = 1;
break;
case 'X':
m->sid |= MBX_EXPERT;
xpert = 1;
break;
case 'N':
m->sid |= MBX_NRID;
break;
case 'R':
m->sid |= MBX_RDMOTD;
break;
case 'S':
m->sid |= MBX_STATS;
break;
case 'L':
m->sid |= MBX_TNOS;
break;
default:
break;
}
cp++;
}
}
} /* while(!found)*/
if (found) {
/* add the new timestamp to the defaults file */
updatedefaults (m, 0);
if (!xpert)
m->sid &= ~MBX_EXPERT;
return laston;
} else {
/* a new one, add to the end (where we now should be!)*/
m->home = strdup ("-");
(void) time (&t);
sprintf (buf, "%s @%s () %lu M%d %s%s%s%s%s C%c\n",
m->name,
(m->home && Hostname && strnicmp (m->home, Hostname, strlen (m->home)))
? m->home : "", t, m->morerows,
(m->privs & IS_BBS) ? "" : (Usearea) ? "A" : "",
(Usehold) ? "H" : "",
(Usenrid) ? "N" : "",
(Usescan) ? "S" : "",
(m->sid & MBX_EXPERT) ? "X" : "",
(m->family == AF_AX25) ? 'A' : \
((m->family == AF_NETROM) ? 'N' : 'T'));
if (Ufile != NULLFILE) { /*lint !e644 */
fputs (buf, Ufile);
(void) fclose (Ufile);
}
m->realname = NULLCHAR;
if (!(m->privs & IS_BBS) && Usearea)
m->sid |= MBX_AREA;
if (Usenrid)
m->sid |= MBX_NRID;
if (Usescan)
m->sid |= MBX_STATS;
return laston;
}
} /* if not bbs */
#endif /* USERLOG */
return (time_t) - 1;
}
/*List all past users of the mailbox */
int
dombpast (int argc, char *argv[], void *p OPTIONAL)
{
register struct pu *pu;
int col = 0;
int maxcount = 10000; /* Large enough :-) */
int count = 0;
if (argc > 1)
maxcount = atoi (argv[1]) - 1;
tputs (past_header);
for (pu = Pu; pu != NULLPU; pu = pu->next) {
if (col)
tputs (" : ");
tprintf ("%-10s %-4d %12s", pu->name, pu->number, \
tformat (secclock () - pu->time));
count++;
if (count > maxcount)
break;
if (col) {
col = 0;
tputc ('\n');
} else
col = 1;
}
if (col)
tputc ('\n');
tputc ('\n');
return 0;
}
static void
smtpqueuecheck ()
{
struct ffblk block;
int done, i = 0;
char buffer[1024];
sprintf (buffer, "%s/*.wrk", Mailqdir);
done = findfirst (buffer, &block, 0x3F);
while (!done) {
i++;
done = findnext (&block);
}
if (i)
tprintf (queued_str, i);
}
int
douptime (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
{
tprintf ("Up: %s\n", tformat (secclock ()));
return 0;
}
int
dombmailstats (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
{
#ifndef UNIX
tputs ("Mem: ");
mbmemory ();
#endif
tprintf (ms_logins, Totallogins, BBSlogins);
#ifdef CONVERS
tprintf (" - CONF: %d", Conflogins);
#endif
#ifdef TUTOR
tprintf (" - TUTOR: %d - INFO: %d - NEWS: %d", Tutorlogins[0], Tutorlogins[1], Tutorlogins[2]);
#endif
tputs (")\n");
(void) douptime (0, (char **) 0, (void *) 0);
tprintf (users_count, BbsUsers, DiffUsers);
#ifdef MBFWD
tprintf ("Users sent: %d\nUsers read: %d\nReceived : %d\nForwarded : %d\n",
MbSent, MbRead, MbRecvd, MbForwarded);
#else
tprintf ("Users sent: %d\nUsers read: %d\nReceived : %d\n", MbSent, MbRead, MbRecvd);
#endif
#ifdef EXPIRY
if (ExpireActive)
tprintf ("Expiration of public area%s %s%s%sin progress\n",
ExpireArea ? "" : "s", ExpireArea ? "\'" : "",
ExpireArea ? ExpireArea : "", ExpireArea ? "\' " : "");
else if (ExpireLast)
tprintf ("Last Expiration: %s", ptime (&ExpireLast));
#endif
smtpqueuecheck ();
#ifdef MAILFOR
(void) domftimer (1, (char **) 0, (void *) 0);
#endif
return 0;
}
#ifdef USERLOG
extern int DTranslate; /* do IP address to domain name translation */
/* Search for info on a certain user in the users.dat file */
int
dombuserinfo (int argc OPTIONAL, char *argv[], void *p)
{
FILE *Ufile;
char buf[MBXLINE];
int found = 0;
time_t t;
struct tm *lt;
char *cp, *home = 0, *cp3 = 0;
char const *cp2;
char *cp4;
struct mbx *m;
char *realname;
uint32 addr;
int trans;
m = (struct mbx *) p;
if ((Ufile = fopen (UDefaults, "r")) == NULLFILE) {
tputs ("Can't find user data\n");
return 0;
}
while (!found && (fgets (buf, MBXLINE, Ufile) != NULLCHAR)) {
if ((cp = strchr (buf, ' ')) == NULLCHAR)
continue;
*cp++ = '\0';
if (!stricmp (buf, argv[1])) { /* Found it ! */
home = Hostname;
if ((cp3 = strchr (cp, ' ')) != NULLCHAR)
*cp3++ = '\0';
if (*cp == '@') {
cp++;
if (*cp)
home = cp;
}
cp = skipwhite (cp3);
realname = NULLCHAR;
if (*cp == '(') {
if ((cp4 = strchr (cp, ')')) != NULLCHAR) {
cp4++;
*cp4++ = '\0';
realname = cp;
cp = cp4;
}
}
cp = skipwhite (cp);
t = atol (cp);
lt = localtime (&t);
cp2 = "TELNET";
if ((cp = strchr (cp, 'C')) != NULLCHAR) {
cp++;
/* How was the connection made ? */
switch (*cp) {
case 'A':
cp2 = "AX.25";
break;
case 'N':
cp2 = "NETROM";
break;
default:
break;
}
}
tprintf (info_on, argv[1], (realname) ? realname : "");
if (m == NULLMBX || m->stype == 'L')
tprintf ("%s last connected via %s on %s", argv[1], cp2, asctime (lt));
#ifdef ASKHOME
tprintf ("%s's HOME BBS", argv[1]);
if (*home == '-')
tputs (" is unknown!\n");
else {
strncpy (buf, home, MBXLINE);
if ((cp = strchr (buf, '.')) != 0)
*cp = 0;
(void) strupr (buf);
tprintf (": '%s'\n", buf);
}
#endif
found = 1;
}
}
(void) fclose (Ufile);
cp2 = wpage_exp (strdup (argv[1]), 1, 1);
if (strchr (cp2, '.')) {
cp4 = strdup (cp2);
(void) strupr (cp4);
tprintf ("%s's WHITE PAGES: '%s'\n", argv[1], cp4);
free (cp4);
} else if (home && Hostname && home == Hostname) {
tprintf ("%s's WHITE PAGES: '", argv[1]);
sprintf (buf, "%s@", argv[1]);
(void) pax25 (&buf[strlen (buf)], Mycall);
if ((cp = strpbrk (buf, DIGI_IDS)) != NULLCHAR)
*cp = '\0'; /* remove SSID */
(void) strupr (buf);
tputs (buf);
#ifdef MBFWD
sprintf (buf, "%s%s'\n", (Mbhaddress != NULLCHAR) ? "." : "",
(Mbhaddress != NULLCHAR) ? Mbhaddress : "");
#else
sprintf (buf, "'\n");
#endif
(void) strupr (buf);
tputs (buf);
}
free (cp2);
if ((addr = resolve (argv[1])) != 0) {
trans = DTranslate; /* Save IP address translation state */
DTranslate = 0; /* Force output to be numeric IP addr */
tprintf (ipaddress_str, argv[1], inet_ntoa (addr));
DTranslate = trans; /* Restore original state */
}
if (!found)
tprintf (nolocal_str, argv[1]);
return 0;
}
#endif
static const char *MBstates[] =
{
"Logging in", "Idle", "Sending message", "Sending message",
"Reverse Forwarding", "Attempting Forward", "Forwarding",
"Using gateway", "Reading message", "Uploading file",
"Downloading file", "Convers mode", "Chatting with sysop",
"Listing files", "Attempting Sysop mode", "Sysop mode",
"Xmodem Receiving", "Xmodem Sending", "Being Tutored",
"Node (idle)", "Unknown state"
};
const char *
displayMBstatus (int state, int issysop)
{
/* Only show callers with sysop-privs who is sysop-mode!
* This prevents users from easily learning who's
* got SYSOP privs
*/
if (!issysop && (state == MBX_SYSOPTRY || state == MBX_SYSOP))
state = MBX_CMD;
if (state < 0 || state > MBX_MAXSTATE)
state = MBX_MAXSTATE + 1;
return MBstates[state];
}
int
dombusers (int argc, char *argv[], void *p)
{
register struct mbx *m, *caller;
int i, len, nerf;
char *cp, *cp1, fsocket[MAXSOCKSIZE];
char upl[60], down[60];
struct usock *up, *up1, *up2;
int s;
time_t elapsedtime;
#ifdef NETROM
struct nrroute_tab *np;
char temp[AXBUF], *cp2, *cp3;
#endif
caller = (struct mbx *) p;
#ifdef MAILCMDS
if (caller->stype == 'H' || caller->stype == 'P' || caller->stype == 'T' || caller->stype == 'A')
return dodelmsg (argc, argv, p);
#endif
if (caller->privs & ALL_AREAS)
return 0; /* can't do this in all areas */
if (caller->stype == 'S')
return dombmailstats (argc, argv, p);
if (caller->stype == 'F' && (caller->privs & SYSOP_CMD)) {
if (argc < 3) {
tputs ("Syntax: MF msg# BBSname\n");
return 0;
}
s = atoi (argv[1]);
if (!s || (caller->nmsgs < s))
tputs (message_oor);
else
updateFwd (argv[2], caller->area, caller->mbox[s].bid, caller->mbox[s].size);
return 0;
}
#ifdef MBFWD
if (caller->stype == 'K' && (caller->privs & SYSOP_CMD)) {
if (argc > 1)
return dombkickone (argc, argv, p);
else
return dombkick (argc, argv, p);
}
#endif
#ifdef EXPIRY
if (caller->stype == 'X' && (caller->privs & SYSOP_CMD)) {
Expiretick (NULL);
return 0;
}
#endif
#ifdef MAILCMDS
if ((caller->stype == 'W' || caller->stype == 'M' || caller->stype == 'C') && (caller->privs & SYSOP_CMD))
return dombmovemail (argc, argv, p);
#endif
if (caller->stype == 'R') {
FILE *fp;
char *from, *to = NULLCHAR, *file, msgtype;
if (!(caller->privs & SYSOP_CMD)) {
tputs ("Only available to SYSOPs, sorry!\n");
return 0;
}
if (argc < 4 || argc > 5) {
tputs (mr_syntax);
return 0;
}
if ((file = permtest (caller->path, caller->privs, argv[2], RETR_CMD, NULLCHAR, 0)) == NULLCHAR)
return 0;
if ((fp = fopen (file, READ_TEXT)) != NULLFILE) {
from = host_or_wpage_exp (strdup ((argc == 5) ? argv[4] : caller->name), 1, 0, &nerf);
msgtype = (char) toupper (argv[1][0]);
if (msgtype != 'B')
to = host_or_wpage_exp (strdup (argv[3]), 1, 0, &nerf);
tputs ("Subject:\n");
if (mbxrecvline (caller) != -1) {
(void) rdaemon (fp, NULLCHAR, from, to, caller->line, msgtype, 0);
tputs ("Message queued\n");
smtptick (NULL); /* wake up SMTP to send mail */
}
(void) fclose (fp);
free (from);
free (to);
} else
tprintf ("Unable to open file '%s'\n", file);
free (file);
return 0;
}
if (caller->stype == 'L')
#ifdef USERLOG
if (argc > 1) {
for (i = 0; i < (int) strlen (argv[1]); i++) {
if (!isdigit (argv[1][i]))
return dombuserinfo (argc, argv, p);
}
return dombpast (argc, argv, p);
} else
#endif
return dombpast (argc, argv, p);
tputs ("Users:\n");
for (i = 0; i < NUMMBX; i++) {
if ((m = Mbox[i]) != NULLMBX) {
len = MAXSOCKSIZE;
if (getpeername (m->user, fsocket, &len) != -1)
cp = strdup (psocket (fsocket));
else
cp = strdup ("unknown");
upl[0] = '\0';
down[0] = '\0';
#if 0
switch (m->family) { /* UPLINK */
#else
up2 = itop (m->user);
if (up2 == NULLUSOCK)
continue;
switch (up2->type) { /* UPLINK */
#endif
#ifdef AX25
#if 0
case AF_AX25:
#else
case TYPE_AX25I:
case TYPE_AX25UI:
#endif
sprintf (upl, Uplink, cp);
break;
#endif
#ifdef NETROM
#if 0
case AF_NETROM:
#else
case TYPE_NETROML3:
case TYPE_NETROML4:
#endif
if ((cp1 = strchr (cp, ' ')) == NULLCHAR)
continue;
*cp1 = '\0';
cp1 += 3;
(void) setcall (temp, cp1);
np = find_nrroute (temp);
if (np != NULLNRRTAB)
cp2 = strdup (np->alias);
else
cp2 = strdup (" ");
if ((cp3 = strchr (cp2, ' ')) != NULLCHAR)
*cp3 = '\0';
/*
if(*cp2 == '#' || *cp2 == '\0')
sprintf(upl,incircuit,cp,"","",cp1);
else
*/
/* show correct user name when outgoing forward over netrom
* problem caused by use of the '.C xxx' lines.
*/
if (m->state == MBX_TRYING || m->state == MBX_FORWARD)
sprintf (upl, incircuit, m->name, cp2, ":", cp1);
else
sprintf (upl, incircuit, cp, cp2, ":", cp1);
free (cp2);
break;
#endif
#if 0
case AF_INET:
#else
case TYPE_TCP:
case TYPE_UDP:
#endif
if ((cp1 = strchr (cp, ':')) != NULLCHAR)
*cp1 = '\0';
sprintf (upl, Telnet, m->name, cp);
/* this fixes a problem where 127.0.0.1 is NOT
recognized as Local, but Telnet */
if (strnicmp (cp, "127.0.0.1", 9))
break;
/*lint -save -e616 * else, fall through and fix the problem */
#if 0
case AF_LOCAL:
#else
case TYPE_LOCAL_STREAM:
case TYPE_LOCAL_DGRAM:
#endif
sprintf (upl, Local, m->name, Hostname);
break;
default:
#if 0
strcpy (upl, "Connect");
break;
#else
/* if it gets here, it is NOT a valid user!
* We will NOT try to free the garbage, though
*/
Mbox[i] = NULLMBX;
continue;
#endif
/*lint -restore */
}
free (cp);
if (m->state == MBX_TRYING) /* forwarding session */
sprintf (upl, fwd_daemon, m->name);
tprintf ("%-38.38s", upl);
/* Show their elapsed time on system - KO4KS */
elapsedtime = 0;
if (m->state != MBX_LOGIN) {
(void) time ((time_t *) & elapsedtime);
elapsedtime -= m->logontime;
}
tprintf (" %10.10s", (m->state == MBX_TRYING) ? "" : tformat ((long) elapsedtime));
/* Now show what they are doing - WG7J */
if (m->state != MBX_GATEWAY)
tputs (" -> ");
switch (m->state) {
case MBX_GATEWAY:
for (s = SOCKBASE; s < Nusock + SOCKBASE; s++) {
if ((up = itop (s)) == NULLUSOCK || s == m->user)
continue;
up1 = itop (m->user);
if (up->owner == up1->owner) {
if (getpeername (s, fsocket, &len) != -1)
cp = strdup (psocket (fsocket));
else
cp = strdup ("unknown");
switch (up->type) {
case TYPE_TCP:
#ifdef notdef
if ((cp1 = strchr (cp, ':')) != NULLCHAR)
*cp1 = '\0';
#endif
sprintf (down, Telnetdown, cp);
break;
#ifdef AX25
case TYPE_AX25I:
/*
if((cp1 = strchr(cp,' ')) != NULLCHAR)
*cp1 = '\0';
*/
sprintf (down, Downlink, cp);
break;
#endif
#ifdef NETROM
case TYPE_NETROML4:
/*get rid of usercall*/
if ((cp1 = strchr (cp, ' ')) == NULLCHAR)
continue;
*cp1 = '\0';
cp1 += 3; /*get rid of ' @ '*/
(void) setcall (temp, cp1); /*get node call*/
np = find_nrroute (temp); /*find alias, if any*/
if (np == NULLNRRTAB)
cp2 = strdup ("???");
else {
cp2 = strdup (np->alias);
if ((cp3 = strchr (cp2, ' ')) != NULLCHAR)
*cp3 = '\0';
/*
memcpy(cp,m->call,AXALEN);
cp[ALEN] ^= 0x1e;
*/
}
/*
if(*cp2 == '#' || *cp2 == '\0')
sprintf(down,outcircuit,"","",cp1);
else
*/
sprintf (down, outcircuit, cp2, ":", cp1);
free (cp2);
break;
#endif
case TYPE_LOCAL_STREAM:
case TYPE_LOCAL_DGRAM:
sprintf (down, Local, m->name, Hostname);
break;
default:
strcpy (down, "Connect");
break;
}
free (cp);
tprintf ("<--> %s", down);
break;
}
}
if (!down[0]) /* couldn't find out where the gateway was TO! */
tputs ("<--> ??INVALID GATEWAY INFO??");
tputs ("\n");
break;
default:
tprintf ("%s\n", displayMBstatus (m->state, (caller->privs & SYSOP_CMD)));
}
}
}
tputc ('\n');
return 0;
}
#if defined(TIPMAIL) && defined(ALLSERV)
static int
dotimeout (int argc, char *argv[], void *p OPTIONAL)
{
return setuns (&Tiptimeout, tiptimeout_str, argc, argv);
}
#endif
#ifdef CALLBOOK
char *InetCallserver = NULLCHAR;
char *InetCallserverport = NULLCHAR;
int
doinetcallserver (int argc, char *argv[], void *p OPTIONAL)
{
if (argc == 1) {
if (InetCallserver != NULLCHAR)
tprintf ("Server %s, on port %s\n", InetCallserver, InetCallserverport);
else
tputs ("Not set!\n");
return 0;
}
if (argc == 2) {
tputs (callusage);
return 0;
}
/*Check validity of the parameters*/
if (resolve (argv[1]) == (int32) 0) {
tprintf (Badhost, argv[1]);
return 0;
}
if (atoi (argv[2]) == (int) 0) {
tprintf ("Bad port %s\n", argv[2]);
return 0;
}
if (InetCallserver != NULLCHAR) {
free (InetCallserver);
free (InetCallserverport);
}
InetCallserver = strdup (argv[1]);
InetCallserverport = strdup (argv[2]);
return 0;
}
#endif /* CALLBOOK */
char *
cmd_line (int argc, char *argv[], char stype)
{
static char line[MBXLINE + 1];
int i;
char *cp;
cp = line;
sprintf (cp, "%s ", argv[0]);
cp += strlen (cp);
if (stype != ' ') {
--cp;
if (islower (*line))
stype = (char) tolower (stype);
sprintf (cp, "%c ", stype);
cp += 2;
}
for (i = 1; i < argc; i++) {
sprintf (cp, "%s ", argv[i]);
cp += strlen (cp);
}
return line;
}
static int
dombcmd (int argc, char *argv[], void *p OPTIONAL)
{
if (argc < 3)
assoc_list (Mbcustom, 10, (argc == 1) ? NULLCHAR : argv[1]);
else
(void) assoc_addstr (&Mbcustom, argv[1], argv[2], 1);
return 0;
}
#ifdef MAILCMDS
static int
dombbonly (int argc, char *argv[], void *p)
{
return (dosetflag (argc, argv, p, BBS_ONLY, 1));
}
#endif
static int
dombuonly (int argc, char *argv[], void *p)
{
return (dosetflag (argc, argv, p, USERS_ONLY, 1));
}
static int
dombsonly (int argc, char *argv[], void *p)
{
return (dosetflag (argc, argv, p, SYSOP_ONLY, 1));
}
int
isaPBBShost (char *str)
{
int k;
char *cp;
/* this routine returns 1 if it looks like an AX25 PBBS name,
otherwise it returns 0 which means it is probably an IP hostname */
for (k = 0; k < numcontinents; k++) {
if (((cp = strstr (str, continents[k])) != NULLCHAR) && (*(cp - 1) == '.') && (*(cp - 5) == '.') && !cp[4])
return 1;
}
return 0;
}
#ifdef ALLSERV
extern int CHAToneshotBypass;
int
dombchat (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
{
int i;
struct mbx *m = NULLMBX;
/* check the mailbox users */
for (i = 0; i < NUMMBX; i++) {
if ((m = Mbox[i]) != NULLMBX) {
if (!stricmp (m->name, argv[1]))
break;
}
}
if (m != NULLMBX && i != NUMMBX) {
MAttended = TRUE; /* force to attended */
CHAToneshotBypass = 1;
if (m->state == MBX_CMD) {
usputc (m->user, '\007');
usputs (m->user, sysopchat);
usflush (m->user);
}
m->privs |= SYS_CHAT;
} else
tprintf (usernoton, argv[1]);
return 0;
}
#endif
void
setMaintenance ()
{
int i;
MBXMaint += 1;
if (MBXMaintMode) {
switch (MBXMaintClear) {
case 1:/* Clear out the BBS - bump users */
for (i = 0; i < NUMMBX; i++) {
if (Mbox[i] != NULLMBX) {
if (MBXMaintStr) {
usprintf (Mbox[i]->user, "\n%s\n", MBXMaintStr);
usflush (Mbox[i]->user);
kpause (5000);
}
close_s (Mbox[i]->user);
}
}
break;
default:
while (BbsUsers)
kpause (1000);
break;
}
}
}
void
clearMaintenance ()
{
MBXMaint -= 1;
}
#ifdef EXPIRY
int
dombprune (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
{
if (newproc ("Pruning", 2048, mbpruning, 0, NULL, NULL, 0) == NULLPROC)
log (-1, "Couldn't start Pruning process");
return 0;
}
int
dombpruneage (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
{
return setint (&PruneAge, pruneage_str, argc, argv);
}
static void
mbpruning (int a OPTIONAL, void *v1 OPTIONAL, void *v2 OPTIONAL)
{
char buf[MBXLINE];
struct ffblk ff;
char *tmp;
log (-1, "BBS Pruning process started");
setMaintenance ();
sprintf (buf, "%s/*.txt", Mailspool);
if (findfirst (buf, &ff, 0) == 0) {
do {
kwait (NULL); /* Let others run */
if ((tmp = strchr (ff.ff_name, '.')) != NULLCHAR)
*tmp = '\0';
if (!issysarea (ff.ff_name))
expire (ff.ff_name, -1);
} while (findnext (&ff) == 0);
}
clearMaintenance ();
log (-1, "BBS Pruning process completed");
}
#endif
#endif /* MAILBOX */